package org.xx.armory.docs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * 表格的单元格元素。
 *
 * @author Haart
 */
public class TableCell
        extends Block
        implements List<Paragraph> {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private final int colSpan;
    private final int rowSpan;
    private final int width;

    private final List<Paragraph> paras;

    /**
     * 构造单元格元素实例。
     *
     * @param className
     *         单元格元素的类名, 会被正规化。
     */
    public TableCell(final String className) {
        this(className, 1, 1, 0);
    }

    /**
     * 构造单元格元素实例。
     *
     * @param className
     *         单元格元素的类名, 会被正规化。
     * @param colSpan
     *         列合并单元格个数, 如果小于{@code 1}则看作{@code 1}。
     * @param rowSpan
     *         行合并单元格个数, 如果小于{@code 1}则看作{@code 1}。
     * @param width
     *         宽度, 如果小于{@code 0}则看作{@code 0}。。
     */
    public TableCell(
            String className,
            int colSpan,
            int rowSpan,
            int width
    ) {
        super(className);

        this.colSpan = colSpan <= 0 ? 1 : colSpan;
        this.rowSpan = rowSpan <= 0 ? 1 : rowSpan;
        this.width = Math.max(width, 0);

        this.paras = new ArrayList<>();
    }

    /**
     * 获取列合并单元格个数。
     *
     * @return 列合并单元格个数。
     */
    public final int getColSpan() {
        return this.colSpan;
    }

    /**
     * 获取行合并单元格个数。
     *
     * @return 行合并单元格个数。
     */
    public final int getRowSpan() {
        return this.rowSpan;
    }

    /**
     * 获取宽度。
     *
     * @return 宽度。
     */
    public final int getWidth() {
        return this.width;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final int size() {
        return this.paras.size();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean isEmpty() {
        return this.paras.isEmpty();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean contains(final Object o) {
        return this.paras.contains(o);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final Iterator<Paragraph> iterator() {
        return this.paras.iterator();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final Object[] toArray() {
        return this.paras.toArray();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("SuspiciousToArrayCall")
    public final <T> T[] toArray(T[] a) {
        return this.paras.toArray(a);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean add(Paragraph e) {
        return this.paras.add(e);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean remove(Object o) {
        return this.paras.remove(o);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean containsAll(Collection<?> c) {
        return this.paras.containsAll(c);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean addAll(Collection<? extends Paragraph> c) {
        return this.paras.addAll(c);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean addAll(
            int index,
            Collection<? extends Paragraph> c
    ) {
        return this.paras.addAll(index, c);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean removeAll(Collection<?> c) {
        return this.paras.removeAll(c);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean retainAll(Collection<?> c) {
        return this.paras.retainAll(c);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final void clear() {
        this.paras.clear();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final Paragraph get(int index) {
        return this.paras.get(index);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final Paragraph set(
            int index,
            Paragraph element
    ) {
        return this.paras.set(index, element);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final void add(
            int index,
            Paragraph element
    ) {
        this.paras.add(index, element);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final Paragraph remove(int index) {
        return this.paras.remove(index);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final int indexOf(Object o) {
        return this.paras.indexOf(o);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final int lastIndexOf(Object o) {
        return this.paras.lastIndexOf(o);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final ListIterator<Paragraph> listIterator() {
        return this.paras.listIterator();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final ListIterator<Paragraph> listIterator(int index) {
        return this.paras.listIterator(index);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final List<Paragraph> subList(
            int fromIndex,
            int toIndex
    ) {
        return this.paras.subList(fromIndex, toIndex);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("<td>");
        for (final Paragraph para : this.paras) {
            sb.append(para);
        }
        sb.append("</td>");
        return sb.toString();
    }
}
